package com.github.chain.admin.api.controller;

import com.github.chain.admin.api.properties.ProjectProperties;
import com.github.chain.admin.api.util.URL;
import com.github.chain.admin.client.RoleServiceClient;
import com.github.chain.admin.common.domain.User;
import com.github.chain.admin.common.enums.AdminErrorMsgEnum;
import com.github.chain.admin.common.request.LoginRequest;
import com.github.chain.admin.common.utils.CaptchaUtil;
import com.github.framework.core.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;


@Controller
@Slf4j
public class LoginController {
    private static final Logger LOGGER = LoggerFactory.getLogger(LoginController.class);

    @Resource
    private ProjectProperties properties;

    @Resource
    private RoleServiceClient roleServiceClient;


    @GetMapping({"/login","/"})
    public String login(Model model){
        boolean captchaOpen = properties.isCaptchaOpen();
        model.addAttribute("isCaptcha",captchaOpen);

        return "login";
    }

    //    @ApiOperation(value = "用户登录")
    @PostMapping("/login")
    @ResponseBody
    public Result login(@Validated LoginRequest loginRequest){

        /**
         * 获取LoginRequest类中的@NotBlank(message = "账户不能为空")注解的message信息
         */
        //if (beanPropertyBindingResult.hasErrors()){
        //    return Result.fail(beanPropertyBindingResult.getAllErrors().get(0).getDefaultMessage());
        //}

        String userName = loginRequest.getUserName();
        String password = loginRequest.getPassword();
        String captcha = loginRequest.getCaptcha();
        String rememberMe = loginRequest.getRememberMe();
        boolean isCaptcha = properties.isCaptchaOpen();

        LOGGER.info("当前系统配置是否需要验证码登录,isCaptcha:{},用户输入验证码为,captcha:{}",isCaptcha,captcha);
        if(isCaptcha){
            Session session = SecurityUtils.getSubject().getSession();
            String sessionCaptcha = (String) session.getAttribute("captcha");
            if (StringUtils.isBlank(captcha) || StringUtils.isBlank(sessionCaptcha)
                    || !captcha.toUpperCase().equals(sessionCaptcha.toUpperCase())) {
                return Result.fail(AdminErrorMsgEnum.USER_LOGIN_CAPTCHA_IS_EMPTY);
            }
            session.removeAttribute("captcha");
        }
        // 1.获取Subject主体对象
        Subject subject = SecurityUtils.getSubject();
        // 2.封装用户数据
        UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
        // 3.执行登录，进入自定义Realm类中
        try {
            // 判断是否自动登录
            if (rememberMe != null) {
                token.setRememberMe(true);
            } else {
                token.setRememberMe(false);
            }
            subject.login(token);

            // 判断是否拥有后台角色
            User user = (User) SecurityUtils.getSubject().getPrincipal();
            Result<Boolean> result = roleServiceClient.findRoleByUserId(user.getId());
            //Result<Boolean> result = null;

            if (result.isSuccess() && result.getData()) {
                return Result.ok(new URL("/main"), "00000000", "登录成功！");
            } else {
                SecurityUtils.getSubject().logout();
                return Result.fail(AdminErrorMsgEnum.USER_IS_NOT_ADMIN);
            }
        }catch(LockedAccountException e) {
            return Result.fail(AdminErrorMsgEnum.USER_ACCOUNT_HAS_BEEN_FROZEN);
        }catch(AuthenticationException e) {
            return Result.fail(AdminErrorMsgEnum.USER_NAME_OR_PASSWORD_IS_INCORRECT);
        }catch(Exception e){
            LOGGER.error("系统异常:",e);
            return Result.fail(AdminErrorMsgEnum.SYSTEM_EXCEPTION);
        }
    }

    @GetMapping("/captcha")
    public void captcha(HttpServletRequest request, HttpServletResponse response) throws IOException {

        //设置响应头信息,通知浏览器不要缓存
        response.setHeader("Expires","-1");
        response.setHeader("Cache-Control","no-cache");
        response.setHeader("Pragma","-1");
        response.setContentType("image/jpeg");
        //获取验证码
        String code = CaptchaUtil.getRandomCode();
        log.error("当前用户登录随机验证码code:{}",code);
        //将验证码输入到session中 用来验证
        request.getSession().setAttribute("captcha",code);
        //输出到web页面
        ImageIO.write(CaptchaUtil.genCaptcha(code),"jpg",response.getOutputStream());
    }

    @GetMapping("/noAuth")
    public String noAuth(){
        //"../static/error/403"
        return "../static/error/403";
    }

    @GetMapping("/logout")
    public String logout() {
        SecurityUtils.getSubject().logout();
        return "redirect:/login";
    }
}
